/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-06-29     18421       the first version
 */

#include "netconnect.h"
#include "dev_4gmodule.h"
#include "rtthread.h"
#include "netupdata.h"
#include "switch.h"

extern Air724_DEVICE_INFO air724ug_info;

#define NET_priority 15
#define NET_timeslices 5
static struct rt_thread netConthread;//线程控制块
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t netConthread_stack[4096];//线程栈

static uint8_t mqttGetDeviceSercet(rt_uint8_t retrynum)
{
    if (air724ug_get_gprs_state() != RT_EOK && rt_strlen(air724ug_info.DeviceId)!=18)
    {
        return RT_ERROR;
    }
    while (retrynum--)
    {

        if (air724x_mqtt_get_DevSercet() == RT_EOK)
        {
            return RT_EOK;
        }
        rt_thread_mdelay(100);
    }
   return RT_ERROR;

}

static uint8_t mqttEstablishConn(void)
{

    if(rt_strlen(air724ug_info.DeviceId)!=18 && air724ug_get_gprs_state()!=RT_EOK )
        return Air724_REGIST_ERR;
    if(air724x_mqtt_DevSercet_status())
    {
        return AIR724_MQTTDEVSECRET_ERR;
    }
    char clientId[30]={0};
    rt_sprintf(clientId, "device-%s",air724ug_info.DeviceId);

    if (air724x_mqtt_connect(MQTT_SERVER_IP, MQTT_SERVER_PORT, clientId, air724ug_info.DeviceId,
            air724ug_info.DeviceSercet) == RT_EOK)
    {
        rt_kprintf("client[%s]connect ok\n",clientId);
        return RT_EOK;
    }
    return Air724_MQTTCON_ERR;
}

uint8_t mqttSubscribeTopic()
{

    if(air724x_mqtt_status()!=1)
    {
        return RT_ERROR;
    }
    char topic[128]={0};
    rt_sprintf(topic, "cmd/%s/%s", air724ug_info.DeviceSercet,CMD_DOWN_CTRL_PARAMETERS);

    if (air724x_mqtt_subscribe(topic,0) != RT_EOK)
    {
        return RT_ERROR;
    }
    rt_kprintf("[netCon]mqtt topic [DownData] subscribe OK\n");

    rt_memset(topic, 0, sizeof(topic));
    rt_sprintf(topic, "%s/%s/%s", OTA_DOWN_TOPIC_HEAD,air724ug_info.DeviceSercet,OTA_DOWN_TOPIC_PARAMETERS);
    if (air724x_mqtt_subscribe(topic, 0) != RT_EOK)
    {
        return RT_ERROR;
    }
    rt_kprintf("[netCon]mqtt topic [ota] subscribe OK\n");
    return RT_EOK;
}



void netConnKeep(void)
{
    uint8_t result=0;
    while (1)
    {
        uint8_t tryTime=0;
        while (1)
        {
            air724x_mqtt_disconnect();
            rt_thread_mdelay(1000);

            tryTime++;
            rt_kprintf("[netCon]air724ug connect mqtt\n");
            result=mqttEstablishConn();
            if (result == RT_EOK)
            {
                rt_kprintf("[NetConn] mqtt conn established!\n");
                break;
            }
            else {
                rt_kprintf("[NetConn] mqtt conn establish error(%d)!\n",result);
            }
            rt_thread_mdelay(1000);
            if(tryTime>=5)
            {
                air724ug_reset();
                rt_thread_mdelay(3000);
                air724ug_init();
                tryTime=0;
            }
        }
        tryTime=0;
        //subscribe
        while (1)
        {
            tryTime++;
            rt_kprintf("[netCon]air724ug subscribe mqtt topic\n");
            if (mqttSubscribeTopic() == RT_EOK)
            {
                result=RT_EOK;
                break;
            }
            if(tryTime>=10)
            {
                result=RT_ERROR;
                break;
            }
            rt_thread_mdelay(1000);
        }
        if(result==RT_ERROR) continue;
        rt_kprintf("[netCon]mqtt topic subscribe OK\n");

        if(RT_EOK!=netupdataEntry())
        {
            rt_kprintf("[dataUp]mqtt topic publish ERROR and net nead Reconnect\n");
        }
        while(scanPowerStatus()==0)
        {
            rt_thread_mdelay(1000);

        }
        //添加上传任务及检测mqtt是否断开
        rt_thread_mdelay(1000);


    }

}

static void netConnect(void* parameter)
{
#define NETCON_TRYNUM   5
    uint8_t result;
    int8_t retrynum=NETCON_TRYNUM;
    mqtt_clear_flag();

//init:
    if (RT_EOK != air724ug_init())
    {
            result = Air724_INIT_ERR;
            goto exit_;
    }

    //tokenGet:
    if (air724x_mqtt_DevSercet_status() != RT_EOK)
    {
        air724x_mqtt_disconnect();//重新烧录时需要，4g模块没有断电，需要重新连接
        rt_kprintf("[netCon]air724ug request token\n");
        if (mqttGetDeviceSercet(retrynum) != RT_EOK)
        {
            //获取DeviceSercet
            result = AIR724_MQTTDEVSECRET_ERR;
            goto exit_;
        }
        //获取到deviceSecret之后需要断开mqtt,使用新的deviceSecret进行连接
    }
    rt_kprintf("[netCon]token[%s] get ok\n",air724ug_info.DeviceSercet);
    netConnKeep();

//connect:


    result=RT_EOK;
exit_:
    switch (result)
    {
    case Air724_INIT_ERR:
        rt_kprintf("[netCon]init get error\n");

        break;
    case AIR724_MQTTDEVSECRET_ERR:
        rt_kprintf("[netCon]productSercet get error\n");
        break;
    default:
        break;
    }

}


int netConnInit(void)
{
//    rt_thread_init(&netinitthread, "netConnect", netConnect,
//       RT_NULL, &netinitthread_stack[0], sizeof(netinitthread_stack), 15, 5);
    at_init();
    rt_thread_init(&netConthread, "netcon", netConnect,
    RT_NULL, &netConthread_stack[0], sizeof(netConthread_stack), 10, 15);

    if (RT_EOK != rt_thread_startup(&netConthread))
    {
        rt_kprintf("beepCtrlWorker Init err\n");
        return 1;
    }
    return 0;
}

INIT_APP_EXPORT(netConnInit);
